home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / c / agl103p.lha / src / agl / rgb.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-09  |  6.7 KB  |  334 lines

  1. /******************************************************************************
  2.  
  3. Copyright © 1994 Jason Weber
  4. All Rights Reserved
  5.  
  6. $Id: rgb.c,v 1.2.1.2 1994/12/09 05:29:56 jason Exp $
  7.  
  8. $Log: rgb.c,v $
  9.  * Revision 1.2.1.2  1994/12/09  05:29:56  jason
  10.  * added copyright
  11.  *
  12.  * Revision 1.2.1.1  1994/11/16  06:57:48  jason
  13.  * added space diffusion
  14.  *
  15.  * Revision 1.2  1994/09/17  05:54:04  jason
  16.  * initial revision
  17.  *
  18.  
  19. ******************************************************************************/
  20.  
  21.  
  22. #ifndef NOT_EXTERN
  23. #include"agl.h"
  24. #endif
  25.  
  26. #define SPACE_DEBUG        FALSE
  27.  
  28.  
  29. #define DISPERSION        0
  30. #define SPACE_DIFFUSION    1
  31.  
  32. #define HALFTONE    SPACE_DIFFUSION
  33.  
  34.  
  35. /* 5 planes, 16 lines */
  36. #define PATTERNSIZE (5*16)
  37.  
  38.  
  39. short Dispersion[4][4]=
  40.     {
  41.      0, 12,  3, 15,
  42.      8,  4, 11,  7,
  43.      2, 14,  1, 13,
  44.     10,  6,  9,  5,
  45.     };
  46.  
  47.  
  48. long SpaceDiffusion[8][8]=
  49.     {
  50.     21, 22, 25, 26, 37, 38, 41, 42,
  51.     20, 23, 24, 27, 36, 39, 40, 43,
  52.     19, 18, 29, 28, 35, 34, 45, 44,
  53.     16, 17, 30, 31, 32, 33, 46, 47,
  54.     15, 12, 11, 10, 53, 52, 51, 48,
  55.     14, 13,  8,  9, 54, 55, 50, 49,
  56.      1,  2,  7,  6, 57, 56, 61, 62,
  57.      0,  3,  4,  5, 58, 59, 60, 63,
  58.     };
  59.  
  60. short DitherMatrix[16][16];
  61.  
  62. float Index_Colors[16][3]=
  63.     {
  64.      0/15.0,  0/15.0,  0/15.0,
  65.     15/15.0,  0/15.0,  0/15.0,
  66.      0/15.0, 15/15.0,  0/15.0,
  67.     15/15.0, 15/15.0,  0/15.0,
  68.      0/15.0,  0/15.0, 15/15.0,
  69.     15/15.0,  0/15.0, 15/15.0,
  70.      0/15.0, 15/15.0, 15/15.0,
  71.     15/15.0, 15/15.0, 15/15.0,
  72.  
  73.      5/15.0,  5/15.0,  5/15.0,
  74.     12/15.0,  7/15.0,  7/15.0,
  75.      7/15.0, 12/15.0,  7/15.0,
  76.      8/15.0,  8/15.0,  3/15.0,
  77.      7/15.0,  7/15.0, 12/15.0,
  78.      8/15.0,  3/15.0,  8/15.0,
  79.      3/15.0,  8/15.0,  8/15.0,
  80.     10/15.0, 10/15.0, 10/15.0,
  81.     };
  82.  
  83.  
  84. UWORD RGBPattern[PATTERNSIZE];
  85.  
  86. long Expo[16];
  87. long DotClass[64][2];
  88.  
  89.  
  90. /******************************************************************************
  91. void    initialize_RGB(void)
  92.  
  93. ******************************************************************************/
  94. /*PROTOTYPE*/
  95. void initialize_RGB(void)
  96.     {
  97.     short x,y;
  98.  
  99.     for(y=0;y<8;y++)
  100.         for(x=0;x<8;x++)
  101.             {
  102.             DotClass[SpaceDiffusion[y][x]][0]=x;
  103.             DotClass[SpaceDiffusion[y][x]][1]=y;
  104.             }
  105.  
  106.     for(y=0;y<16;y++)
  107.         {
  108.         for(x=0;x<16;x++)
  109.             DitherMatrix[y][x]=Dispersion[y/4][x/4]+Dispersion[y&3][x&3]*16;
  110.  
  111.         Expo[y]=1<<y;
  112.         }
  113.  
  114.     memset(RGBPattern,0,PATTERNSIZE*sizeof(UWORD));
  115.     }
  116.  
  117.  
  118. /******************************************************************************
  119. void    c3f(float rgb[3])
  120.  
  121. ******************************************************************************/
  122. /*PROTOTYPE*/
  123. void c3f(float rgb[3])
  124.     {
  125.     create_pattern(RGBPattern,rgb);
  126.     activate_pattern(RGBPattern);
  127.     }
  128.  
  129.  
  130. /******************************************************************************
  131. float    index_dist(short index,float rgb[3])
  132.  
  133.     return square of distance to index in color space
  134.  
  135.     Note: sqrt() unneccasary since just finding minimum
  136. ******************************************************************************/
  137. /*PROTOTYPE*/
  138. float index_dist(short index,float rgb[3])
  139.     {
  140.     float dx,dy,dz;
  141.  
  142.     dx=rgb[0]-Index_Colors[index][0];
  143.     dy=rgb[1]-Index_Colors[index][1];
  144.     dz=rgb[2]-Index_Colors[index][2];
  145.  
  146.     return    dx*dx+dy*dy+dz*dz;
  147.     }
  148.  
  149.  
  150. /******************************************************************************
  151. void    create_pattern(UWORD *pattern,float rgb[3])
  152.  
  153. ******************************************************************************/
  154. /*PROTOTYPE*/
  155. void create_pattern(UWORD *pattern,float rgb[3])
  156.     {
  157.     float mod[8][8][3],error[3];
  158.     float add,total;
  159.     float red,green,blue;
  160.     float best_dist,new_dist;
  161.  
  162.     short class;
  163.     short contribution;
  164.     short best_index,new_index;
  165.     short plane,x,y,i,j,m,pass;
  166.     short component;
  167.     
  168.     if(HALFTONE==SPACE_DIFFUSION)
  169.         {
  170.         /* initialize */
  171.         for(y=0;y<8;y++)
  172.             for(x=0;x<8;x++)
  173.                 {
  174.                 mod[y][x][0]=rgb[0];
  175.                 mod[y][x][1]=rgb[1];
  176.                 mod[y][x][2]=rgb[2];
  177.                 }
  178.  
  179.         for(plane=0;plane<5;plane++)
  180.             for(y=0;y<16;y++)
  181.                 pattern[plane*16+y]=0;
  182.  
  183.         for(class=0;class<64;class++)
  184.             {
  185.             x=DotClass[class][0];
  186.             y=DotClass[class][1];
  187.  
  188.             if(SpaceDiffusion[y][x]!=class)
  189.                 GL_error("Class mismatch in create_pattern()");
  190.  
  191.             red=mod[y][x][0];
  192.             green=mod[y][x][1];
  193.             blue=mod[y][x][2];
  194.  
  195.             /* find nearest match */
  196.             best_index= ((((blue>0.5)<<1)+(green>0.5))<<1) + (red>0.5);
  197.             best_dist=index_dist(best_index,mod[y][x]);
  198.  
  199. #if SPACE_DEBUG
  200.             printf("%d: %4.2f,%4.2f,%4.2f %d(%.6G) ",class,red,green,blue,best_index,best_dist);
  201. #endif
  202.  
  203.             /* compare with middle colors */
  204.             j=0;
  205.             for(m=0;m<4;m++)
  206.                 {
  207.                 switch(m)
  208.                     {
  209.                     case 0:
  210.                         if(red>0.5)
  211.                             {
  212.                             new_index=PINK;
  213.                             j++;
  214.                             }
  215.                         else
  216.                             new_index=BLUEGREEN;
  217.                         break;
  218.                     case 1:
  219.                         if(green>0.5)
  220.                             {
  221.                             new_index=LIGHTGREEN;
  222.                             j++;
  223.                             }
  224.                         else
  225.                             new_index=PURPLE;
  226.                         break;
  227.                     case 2:
  228.                         if(blue>0.5)
  229.                             {
  230.                             new_index=LAVENDER;
  231.                             j++;
  232.                             }
  233.                         else
  234.                             new_index=OLIVE;
  235.                         break;
  236.                     case 3:
  237.                         if(j>1)
  238.                             new_index=LIGHTGREY;
  239.                         else
  240.                             new_index=DARKGREY;
  241.                         break;
  242.                     }
  243.  
  244. #if SPACE_DEBUG
  245.                 printf("%d.",new_index);
  246. #endif
  247.  
  248.                 new_dist=index_dist(new_index,mod[y][x]);
  249.                 if(best_dist>new_dist)
  250.                     {
  251.                     best_dist=new_dist;
  252.                     best_index=new_index;
  253.  
  254. #if SPACE_DEBUG
  255.                     printf("-> %d(%.6G) ",best_index,best_dist);
  256. #endif
  257.                     }
  258.                 }
  259.  
  260.             /* set index */
  261.             for(plane=0;plane<5;plane++)
  262.                 if(best_index&Expo[plane])
  263.                     {
  264.                     pattern[plane*16+y  ]+=Expo[x];
  265.                     pattern[plane*16+y+8]+=Expo[x];
  266.  
  267.                     pattern[plane*16+y  ]+=Expo[x+8];
  268.                     pattern[plane*16+y+8]+=Expo[x+8];
  269.                     }
  270.  
  271.             error[0]= mod[y][x][0]-Index_Colors[best_index][0];
  272.             error[1]= mod[y][x][1]-Index_Colors[best_index][1];
  273.             error[2]= mod[y][x][2]-Index_Colors[best_index][2];
  274.  
  275. #if SPACE_DEBUG
  276.             printf("e %4.2f,%4.2f,%4.2f\n",error[0],error[1],error[2]);
  277. #endif
  278.             
  279.             total=0;
  280.             for(pass=0;pass<2;pass++)
  281.                 for(j= -1;j<2;j++)
  282.                     for(i= -1;i<2;i++)
  283.                         if( !( (i==0 && j==0) ||    (i<0 && x==0) || (i>0 && x==7) ||
  284.                                                     (j<0 && y==0) || (j>0 && y==7) ||
  285.                                                     SpaceDiffusion[y+j][x+i]<class ) )
  286.                             {
  287.                             contribution= 1 + (i==0 || j==0);
  288.  
  289.                             if(pass==0)
  290.                                 total+=contribution;
  291.                             else
  292.                                 for(m=0;m<3;m++)
  293.                                     {
  294.                                     add= error[m] * contribution/total;
  295.                                     mod[y+j][x+i][m]+=add;
  296.                                     }
  297.                             }
  298.             }
  299.  
  300. #if SPACE_DEBUG
  301.         exit(1);
  302. #endif
  303.         }
  304.     else
  305.         for(plane=0;plane<3;plane++)
  306.             {
  307.             component=255*rgb[plane];
  308.  
  309.             for(y=0;y<16;y++)
  310.                 {
  311.                 pattern[plane*16+y]=0;
  312.  
  313.                 for(x=0;x<16;x++)
  314.                     if(DitherMatrix[y][x]<component)
  315.                         pattern[plane*16+y]+=Expo[x];
  316.                 }
  317.             }
  318.     }
  319.  
  320.  
  321. /******************************************************************************
  322. void    activate_pattern(UWORD *pattern)
  323.  
  324.     NULL pattern should deactivate current pattern
  325. ******************************************************************************/
  326. /*PROTOTYPE*/
  327. void activate_pattern(UWORD *pattern)
  328.     {
  329.     SetAfPt(DrawRPort,pattern,-4);
  330.     SetAPen(DrawRPort,255);
  331.     SetBPen(DrawRPort,0);
  332.     SetDrMd(DrawRPort,JAM2);
  333.     }
  334.